home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / sat / msat09.tgz / MESSAGE.C < prev    next >
Text File  |  1994-09-17  |  25KB  |  984 lines

  1. /*
  2.  *   Copyright 1992, 1993, 1994 John Melton (G0ORX/N6LYT)
  3.  *              All Rights Reserved
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 1, or (at your option)
  8.  *   any later version.
  9.  *
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *   GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program; if not, write to the Free Software
  17.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20.  
  21. /*
  22.     message.c
  23.  
  24.     Prepare a PacSat message for uploading
  25.  
  26.     John Melton
  27.     G0ORX, N6LYT
  28.  
  29.     4 Charlwoods Close
  30.     Copthorne
  31.     West Sussex
  32.     RH10 3QZ
  33.     England
  34.  
  35.     INTERNET:    g0orx@amsat.org
  36.             n6lyt@amsat.org
  37.             john@images.demon.co.uk
  38.             J.D.Melton@slh0613.icl.wins.co.uk
  39.  
  40.     History:
  41.  
  42.     0.1    initial version.                    G0ORX
  43.     0.2    fixed file length in header.                G0ORX
  44.     0.3    converted to Xaw.                    G4KLX
  45.         removed size restriction on message and banner.
  46.     0.4    restructured screen and code.                G4KLX
  47.     0.5    added quoting of original message.            G4KLX
  48. */
  49.  
  50. #define INSERTCRLF
  51.  
  52. #define VERSION_STRING "message (version 0.5 by g0orx/n6lyt/g4klx)"
  53.  
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include <unistd.h>
  57. #include <sys/types.h>
  58. #include <fcntl.h>
  59. #include <dirent.h>
  60. #include <time.h>
  61.  
  62. #include <X11/Intrinsic.h>
  63. #include <X11/StringDefs.h>
  64. #include <X11/Shell.h>
  65. #include <X11/Xaw/Cardinals.h>
  66. #include <X11/Xaw/Form.h>
  67. #include <X11/Xaw/Text.h>
  68. #include <X11/Xaw/AsciiText.h>
  69. #include <X11/Xaw/Label.h>
  70. #include <X11/Xaw/Command.h>
  71. #include <X11/Xaw/MenuButton.h>
  72.  
  73. #include "xawutils.h"
  74. #include "header.h"
  75. #include "ftl0.h"
  76.  
  77. Display *dpy;
  78.  
  79. XtAppContext app_context;
  80.  
  81. typedef struct
  82. {
  83.     XFontStruct *bold_font, *button_font, *menu_font, *label_font, *text_font;
  84. }
  85. Resources;
  86.  
  87. Resources  resources;
  88.  
  89. Widget toplevel, compwindow, quitbutton, preparebutton, bannerbutton,
  90.     quotebutton, fromlabel, fromtext, tolabel, totext, titlelabel,
  91.     titletext, keywordslabel, keywordstext, filetypebutton, filetypelabel,
  92.     filetypetext, comptypebutton, comptypelabel, comptypetext, mesgsrclabel,
  93.     mesgsrcbutton, mesgsrctext, datawindow;
  94.  
  95. static XtResource resource_list[] =
  96. {
  97.     {"boldFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  98.         XtOffsetOf(Resources, bold_font), XtRString, XtDefaultFont},
  99.     {"buttonFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  100.         XtOffsetOf(Resources, button_font), XtRString, XtDefaultFont},
  101.     {"menuFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  102.         XtOffsetOf(Resources, menu_font), XtRString, XtDefaultFont},
  103.     {"labelFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  104.         XtOffsetOf(Resources, label_font), XtRString, XtDefaultFont},
  105.     {"textFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  106.         XtOffsetOf(Resources, text_font), XtRString, XtDefaultFont}
  107. };
  108.  
  109. static Arg shell_args[] =
  110. {
  111.     {XtNtitle,        (XtArgVal)NULL}
  112. };
  113.  
  114. static Arg form_args[] =
  115. {
  116.     {XtNdefaultDistance,    (XtArgVal)0}
  117. };
  118.  
  119. static Arg label_args[] =
  120. {
  121.     {XtNfromVert,        (XtArgVal)NULL},
  122.     {XtNlabel,        (XtArgVal)NULL},
  123.     {XtNwidth,        (XtArgVal)0},
  124.     {XtNfont,        (XtArgVal)NULL},
  125.     {XtNborderWidth,    (XtArgVal)0},
  126.     {XtNresize,        False},
  127.     {XtNjustify,        XtJustifyLeft},
  128.     {XtNvertDistance,    (XtArgVal)6},
  129.     {XtNhorizDistance,    (XtArgVal)8},
  130.     {XtNtop,        XtChainTop},
  131.     {XtNbottom,        XtChainTop},
  132.     {XtNleft,        XtChainLeft},
  133.     {XtNright,        XtChainLeft}
  134. };
  135.  
  136. static Arg button_args[] =
  137. {
  138.     {XtNcallback,        (XtArgVal)NULL},
  139.     {XtNlabel,        (XtArgVal)NULL},
  140.     {XtNfont,        (XtArgVal)NULL},
  141.     {XtNfromHoriz,        (XtArgVal)NULL},
  142.     {XtNvertDistance,    (XtArgVal)6},
  143.     {XtNhorizDistance,    (XtArgVal)8},
  144.     {XtNresize,        False},
  145.     {XtNtop,        XtChainTop},
  146.     {XtNbottom,        XtChainTop},
  147.     {XtNleft,        XtChainLeft},
  148.     {XtNright,        XtChainLeft}
  149. };
  150.  
  151. static Arg menu_button_args[] =
  152. {
  153.     {XtNlabel,        (XtArgVal)NULL},
  154.     {XtNfromHoriz,        (XtArgVal)NULL},
  155.     {XtNfromVert,        (XtArgVal)NULL},
  156.     {XtNwidth,        (XtArgVal)0},
  157.     {XtNfont,        (XtArgVal)NULL},
  158.     {XtNresize,        False},
  159.     {XtNvertDistance,    (XtArgVal)6},
  160.     {XtNhorizDistance,    (XtArgVal)8},
  161.     {XtNtop,        XtChainTop},
  162.     {XtNbottom,        XtChainTop},
  163.     {XtNleft,        XtChainLeft},
  164.     {XtNright,        XtChainLeft},
  165.     {XtNjustify,        XtJustifyCenter}
  166. };
  167.  
  168. static Arg text_args[] =
  169. {
  170.     {XtNfromHoriz,        (XtArgVal)NULL},
  171.     {XtNfromVert,        (XtArgVal)NULL},
  172.     {XtNlength,        (XtArgVal)255},
  173.     {XtNwidth,        (XtArgVal)500},
  174.     {XtNstring,        (XtArgVal)NULL},
  175.     {XtNfont,        (XtArgVal)NULL},
  176.     {XtNbackground,        (XtArgVal)NULL},
  177.     {XtNvertDistance,    (XtArgVal)6},
  178.     {XtNhorizDistance,    (XtArgVal)8},
  179.     {XtNtop,        XtChainTop},
  180.     {XtNbottom,        XtChainTop},
  181.     {XtNleft,        XtChainLeft},
  182.     {XtNright,        XtChainLeft},
  183.     {XtNeditType,        XawtextEdit},
  184.     {XtNtype,        XawAsciiString},
  185.     {XtNresize,        False},
  186.     {XtNuseStringInPlace,    True}
  187. };
  188.  
  189. static Arg window_args[] =
  190. {
  191.     {XtNfromVert,        (XtArgVal)NULL},
  192.     {XtNbackground,        (XtArgVal)NULL},
  193.     {XtNfont,        (XtArgVal)NULL},
  194.     {XtNwidth,        (XtArgVal)600},
  195.     {XtNheight,        (XtArgVal)200},
  196.     {XtNvertDistance,    (XtArgVal)10},
  197.     {XtNhorizDistance,    (XtArgVal)0},
  198.     {XtNtop,        XtChainTop},
  199.     {XtNbottom,        XtChainBottom},
  200.     {XtNleft,        XtChainLeft},
  201.     {XtNright,        XtChainRight},
  202.     {XtNeditType,        XawtextEdit},
  203.     {XtNtype,        XawAsciiString},
  204.     {XtNwrap,        XawtextWrapWord},
  205.     {XtNscrollVertical,    XawtextScrollAlways}
  206. };
  207.  
  208. MenuEntry comp_type_menu[] =
  209. {
  210.     {"Not Compressed",    "comptype1",    0},
  211.     {"PKARC",        "comptype2",    1},
  212.     {"PKZIP",        "comptype3",    2},
  213.     {"LHARC",        "comptype4",    3},
  214.     {"Other -->",        "comptype5",    255}
  215. };
  216.  
  217. MenuEntry mesg_src_menu[] =
  218. {
  219.     {"Inline Text",        "mesgsrc1",    0},
  220.     {"File -->",        "mesgsrc2",    1}
  221. };
  222.  
  223. MenuEntry file_type_menu[] =
  224. {
  225.     {"ASCII text",            "filetype1",    0},
  226.     {"RLI/MBL message (single)",    "filetype2",    1},
  227.     {"RLI/MBL message (multiple)",    "filetype3",    2},
  228.     {"MS/PC-DOS .exe",        "filetype4",    6},
  229.     {"MS/PC-DOS .com",        "filetype5",    7},
  230.     {"Keps (NASA 2-line)",        "filetype6",    8},
  231.     {"Keps (AMSAT)",        "filetype7",    9},
  232.     {"Multiple messages",        "filetype8",    12},
  233.     {"Multiple messages (ASCII)",    "filetype9",    13},
  234.     {"GIF image",            "filetype10",    14},
  235.     {"PCX image",            "filetype11",    15},
  236.     {"JPEG image",            "filetype12",    16},
  237.     {"Other -->",            "filetype13",    255}
  238. };
  239.  
  240. char *fileName = NULL;
  241.  
  242. HEADER *pHeader;
  243.  
  244. int filetype = 0;
  245. int comptype = 0;
  246. int mesgsrc  = 0;
  247.  
  248. char satelliteId[16];
  249.  
  250. char myCall[256]        = "";
  251. char toCall[256]        = "";
  252. char title[256]         = "";
  253. char keywords[256]      = "";
  254. char filetype_text[256] = "";
  255. char comptype_text[256] = "";
  256. char mesgsrc_text[256]  = "";
  257.  
  258. char banner[256];
  259.  
  260. #define MAXHEADER 2048
  261.  
  262. unsigned char header[MAXHEADER];
  263. int nHeader = 0;
  264.  
  265. int PrepareFile(unsigned char *);
  266.  
  267. void QuitCb(Widget w, XtPointer client_data, XtPointer call_data)
  268. {
  269.     XtDestroyApplicationContext(app_context);
  270.  
  271.     exit(0);
  272. }
  273.  
  274. void BannerCb(Widget w, XtPointer client_data, XtPointer call_data)
  275. {
  276.     FILE *fp;
  277.     static char text[1000];
  278.     int bytes;
  279.     XawTextPosition pos, oldpos;
  280.     XawTextBlock tt;
  281.     Arg args[1];
  282.     String string;
  283.     
  284.     if ((fp = fopen(banner, "r")) != NULL)
  285.     {
  286.         XtSetArg(args[0], XtNstring, &string);
  287.         XtGetValues(datawindow, args, 1);
  288.         pos = strlen(string);
  289.  
  290.         oldpos = XawTextGetInsertionPoint(datawindow);
  291.     
  292.         while ((bytes = fread(text, 1, 1000, fp)) > 0)
  293.         {
  294.             XawTextSetInsertionPoint(datawindow, pos);
  295.         
  296.             tt.firstPos = 0;
  297.             tt.ptr      = text;
  298.             tt.length   = bytes;
  299.             tt.format   = FMT8BIT;
  300.  
  301.             XawTextReplace(datawindow, pos, pos, &tt);
  302.             pos += bytes;
  303.         }
  304.         
  305.         fclose(fp);
  306.  
  307.         XawTextSetInsertionPoint(datawindow, oldpos);
  308.     }
  309. }
  310.  
  311. void ExtractDetails(void)
  312. {
  313.     char *pBuffer;
  314.     FILE *hFile;
  315.     int headerSize;
  316.     int nBytes;
  317.     
  318.     /* open the file */
  319.     if ((hFile = fopen(fileName, "r")) == NULL)
  320.     {
  321.         MessageBox("Cannot open input file");
  322.         return;
  323.     }
  324.  
  325.     pBuffer = XtMalloc(1024);
  326.  
  327.     /* read in the header */
  328.     nBytes = fread(pBuffer, 1, 1024, hFile);
  329.  
  330.     /* extracting the header */
  331.     if ((pHeader = ExtractHeader(pBuffer, nBytes, &headerSize)) == NULL)
  332.     {
  333.         MessageBox("Cannot extract PACSAT header");
  334.         XtFree(pBuffer);
  335.         fclose(hFile);
  336.         return;
  337.     }
  338.  
  339.     strcpy(toCall, pHeader->source);
  340.     sprintf(title, "Re: %s", pHeader->title);
  341.  
  342.     XtFree(pBuffer);
  343.     fclose(hFile);
  344. }
  345.  
  346. void QuoteCb(Widget w, XtPointer client_data, XtPointer call_data)
  347. {
  348.     char *pBuffer, *pOutBuffer;
  349.     FILE *hFile;
  350.     FILE *hOut;
  351.     int nBytes, nOutBytes;
  352.     int status, i;
  353.     XawTextPosition pos = 0;
  354.     XawTextBlock tt;
  355.     char command[40];
  356.     char compFile[20], viewFile[20];
  357.     time_t t;
  358.     
  359.     /* open the file */
  360.     if ((hFile = fopen(fileName, "r")) == NULL)
  361.     {
  362.         MessageBox("Cannot open input file");
  363.         return;
  364.     }
  365.  
  366.     pBuffer = XtMalloc(1024);
  367.  
  368.     if (pHeader->compression != 0 && pHeader->compression != 255)
  369.     {
  370.         time(&t);
  371.     
  372.         sprintf(compFile, "%x.comp", (int)t);
  373.         sprintf(viewFile, "%x.view", (int)t);
  374.     
  375.         fseek(hFile, pHeader->bodyOffset, SEEK_SET);
  376.  
  377.         if ((hOut = fopen(compFile, "w")) == NULL)
  378.         {
  379.             MessageBox("Cannot open output file");
  380.             return;
  381.         }
  382.  
  383.         while ((nBytes = fread(pBuffer, 1, 1024, hFile)) > 0)
  384.             fwrite(pBuffer, 1, nBytes, hOut);
  385.  
  386.         fclose(hFile);
  387.         fclose(hOut);
  388.     
  389.         switch (pHeader->compression)
  390.         {
  391.         case 2:
  392.             sprintf(command, "unzip -p %s > %s", compFile, viewFile);
  393.             break;
  394.         case 3:
  395.             sprintf(command, "lha -pq %s > %s", compFile, viewFile);
  396.             break;
  397.         default:
  398.             break;
  399.         }
  400.  
  401.         status = system(command);
  402.  
  403.         if (status == 127 || status < 0)
  404.         {
  405.             unlink(compFile);
  406.             MessageBox("Cannot run unzip/lha");
  407.             return;
  408.         }
  409.  
  410.         if ((hFile = fopen(viewFile, "r")) == NULL)
  411.         {
  412.             unlink(compFile);
  413.             MessageBox("Cannot open input file");
  414.             return;
  415.         }
  416.     }
  417.     
  418.     /* now copy in the text */
  419.     if (pHeader->compression == 0)
  420.         fseek(hFile, pHeader->bodyOffset, SEEK_SET);
  421.  
  422.     pOutBuffer = XtMalloc(2048);
  423.  
  424.     pOutBuffer[0] = '>';
  425.     pOutBuffer[1] = ' ';
  426.     nOutBytes     = 2;
  427.  
  428.     while ((nBytes = fread(pBuffer, 1, 1024, hFile)) > 0)
  429.     {
  430.         for (i = 0; i < nBytes; i++)
  431.         {
  432.             if (pBuffer[i] >= ' ' && pBuffer[i] <= '~')
  433.                 pOutBuffer[nOutBytes++] = pBuffer[i];
  434.                 
  435.             if (pBuffer[i] == '\n')
  436.             {
  437.                 pOutBuffer[nOutBytes++] = '\n';
  438.                 pOutBuffer[nOutBytes++] = '>';
  439.                 pOutBuffer[nOutBytes++] = ' ';
  440.             }
  441.         }
  442.  
  443.         tt.firstPos = 0;
  444.         tt.ptr      = pOutBuffer;
  445.         tt.length   = nOutBytes;
  446.         tt.format   = FMT8BIT;
  447.  
  448.         XawTextReplace(datawindow, pos, pos, &tt);
  449.  
  450.         pos += nOutBytes;
  451.  
  452.         nOutBytes = 0;
  453.     }
  454.  
  455.     fclose(hFile);
  456.  
  457.     if (pHeader->compression != 0)
  458.     {
  459.         unlink(compFile);
  460.         unlink(viewFile);
  461.     }
  462.  
  463.     XtFree(pBuffer);
  464.     XtFree(pOutBuffer);
  465. }
  466.  
  467. void PrepareCb(Widget w, XtPointer client_data, XtPointer call_data)
  468. {
  469.     unsigned char *src;
  470.     Arg args[1];
  471.  
  472.     XtSetArg(args[0], XtNstring, &src);
  473.     XtGetValues(datawindow, args, 1);
  474.  
  475. #ifdef INSERTCRLF
  476.     {
  477.         int  length;
  478.         unsigned char *dest, *text;
  479.  
  480.         length = strlen(src);
  481.  
  482.         for (dest = src; *dest != '\0'; dest++)
  483.             if (*dest == '\n')
  484.                 length++;
  485.  
  486.         if ((text = XtMalloc(length + 1)) == NULL)
  487.         {
  488.             MessageBox("Out of memory");
  489.             return;
  490.         }
  491.  
  492.         dest = text;
  493.  
  494.         while (*src)
  495.         {
  496.             if (*src == '\n') *dest++ = '\r';
  497.             *dest++ = *src++;
  498.         }
  499.  
  500.         *dest++ = '\0';
  501.  
  502.         /* prepare the header and the data */
  503.         PrepareFile(text);
  504.  
  505.         XtFree(text);
  506.     }
  507. #else
  508.     /* prepare the header and the data */
  509.     PrepareFile(src);
  510. #endif
  511. }
  512.  
  513. void HeaderOut(int v)
  514. {
  515.     if (nHeader < MAXHEADER)
  516.     {
  517.         header[nHeader] = v;
  518.         nHeader++;
  519.     }
  520. }
  521.  
  522. void Header(unsigned int id, char *string, int length)
  523. {
  524.     int i;
  525.  
  526.     HeaderOut(id % 256);
  527.     HeaderOut(id / 256);
  528.     HeaderOut(length);
  529.  
  530.     for (i = 0; i < length; i++)
  531.         HeaderOut(string[i]);
  532. }
  533.  
  534. int PrepareFile(unsigned char *text)
  535. {
  536.     time_t uploadSeq;
  537.     FILE *fpin, *fpout;
  538.     char OutFile[20], InFile[20];
  539.     int i, Bytes;
  540.     int updateFileSize, updateBodyChecksum, updateHeaderChecksum;
  541.     int updateBodyOffset, savedHeaderOffset;
  542.     unsigned char buffer[512];
  543.     unsigned char  int8  = 0;
  544.     unsigned short int16 = 0;
  545.     unsigned long  int32 = 0;
  546.     unsigned short HeaderChecksum = 0;
  547.     unsigned short BodyChecksum   = 0;
  548.     unsigned int   FileSize       = 0;
  549.     unsigned short BodyOffset     = 0;
  550.  
  551.     time(&uploadSeq);
  552.  
  553.     if (mesgsrc == 0)
  554.         sprintf(InFile, "%x.txt", (int)uploadSeq);
  555.  
  556.     sprintf(OutFile, "%x.upl", (int)uploadSeq);
  557.  
  558.     nHeader = 0;
  559.  
  560.     HeaderOut(0xAA);
  561.     HeaderOut(0x55);
  562.  
  563.     Header(0x01, (char *)&int32, 4);
  564.     Header(0x02, (char *)"        ", 8);
  565.     Header(0x03, (char *)"   ", 3);
  566.     updateFileSize = nHeader;
  567.  
  568.     Header(0x04, (char *)&int32, 4);
  569.     Header(0x05, (char *)&int32, 4);
  570.     Header(0x06, (char *)&int32, 4);
  571.     Header(0x07, (char *)&int8, 1);
  572.  
  573.     int8 = filetype;
  574.     Header(0x08, (char *)&int8, 1);
  575.     updateBodyChecksum = nHeader;
  576.  
  577.     Header(0x09, (char *)&int16, 2);
  578.     updateHeaderChecksum = nHeader;
  579.  
  580.     Header(0x0A, (char *)&int16, 2);
  581.     updateBodyOffset = nHeader;
  582.  
  583.     int8 = 0;
  584.     Header(0x0B, (char *)&int16, 2);
  585.     Header(0x10, (char *)myCall, strlen(myCall));
  586.     Header(0x11, (char *)"      ", 6);
  587.     Header(0x12, (char *)&int32, 4);
  588.     Header(0x13, (char *)&int8, 1);
  589.     Header(0x14, (char *)toCall, strlen(toCall));
  590.     Header(0x15, (char *)"      ", 6);
  591.     Header(0x16, (char *)&int32, 4);
  592.     Header(0x17, (char *)&int32, 4);
  593.     Header(0x18, (char *)&int8, 1);
  594.  
  595.     int8 = comptype;
  596.     Header(0x19, (char *)&int8, 1);
  597.  
  598.     Header(0x22, title, strlen(title));
  599.  
  600.     if (strlen(keywords) != 0)
  601.         Header(0x23, keywords, strlen(keywords));
  602.  
  603.     if (filetype == 255)
  604.         Header(0x24, filetype_text, strlen(filetype_text));
  605.  
  606.     if (comptype == 255)
  607.         Header(0x25, comptype_text, strlen(comptype_text));
  608.  
  609.     if (mesgsrc == 0)
  610.         Header(0x26, InFile, strlen(InFile));
  611.     else
  612.         Header(0x26, mesgsrc_text, strlen(mesgsrc_text));
  613.  
  614.     HeaderOut(0x00);
  615.     HeaderOut(0x00);
  616.     HeaderOut(0x00);
  617.     savedHeaderOffset = nHeader;
  618.  
  619.     BodyOffset = nHeader;
  620.  
  621.     nHeader = updateBodyOffset;
  622.     Header(0x0B, (char *)&BodyOffset, 2);
  623.  
  624.     nHeader = savedHeaderOffset;
  625.  
  626.     FileSize = nHeader;
  627.  
  628.     if (mesgsrc == 0)
  629.     {
  630.         if ((fpout = fopen(OutFile, "w")) == NULL)
  631.         {
  632.             MessageBox("Cannot open output file");
  633.             return(FALSE);
  634.         }
  635.  
  636.         fseek(fpout, BodyOffset, SEEK_SET);
  637.  
  638.         fwrite(text, 1, strlen(text), fpout);
  639.  
  640.         for (i = 0; i < strlen(text); i++)
  641.             BodyChecksum += (unsigned int)text[i];
  642.  
  643.         FileSize = nHeader + strlen(text);
  644.     }
  645.     else
  646.     {
  647.         if ((fpin = fopen(mesgsrc_text, "r")) == NULL)
  648.         {
  649.             MessageBox("Cannot open input file");
  650.             return(FALSE);
  651.         }
  652.  
  653.         if ((fpout = fopen(OutFile, "w")) == NULL)
  654.         {
  655.             fclose(fpin);
  656.             MessageBox("Cannot open output file");
  657.             return(FALSE);
  658.         }
  659.  
  660.         fseek(fpout, BodyOffset, SEEK_SET);
  661.  
  662.         while ((Bytes = fread(buffer, 1, sizeof(buffer), fpin)) > 0)
  663.         {
  664.             FileSize += Bytes;
  665.  
  666.             fwrite(buffer, 1, Bytes, fpout);
  667.  
  668.             for (i = 0; i < Bytes; i++)
  669.                 BodyChecksum += (unsigned int)buffer[i];
  670.         }
  671.  
  672.         fclose(fpin);
  673.     }
  674.  
  675.     savedHeaderOffset = nHeader;
  676.  
  677.     nHeader = updateBodyChecksum;
  678.     Header(0x09, (char *)&BodyChecksum, 2);
  679.  
  680.     nHeader = savedHeaderOffset;
  681.     savedHeaderOffset = nHeader;
  682.  
  683.     nHeader = updateFileSize;
  684.     Header(0x04, (char *)&FileSize, 4);
  685.  
  686.     nHeader = savedHeaderOffset;
  687.     for (i = 0; i < nHeader; i++)
  688.         HeaderChecksum += (unsigned int)header[i];
  689.     savedHeaderOffset = nHeader;
  690.  
  691.     nHeader = updateHeaderChecksum;
  692.     Header(0x0A, (char *)&HeaderChecksum, 2);
  693.  
  694.     nHeader = savedHeaderOffset;
  695.  
  696.     fseek(fpout, 0L, SEEK_SET);
  697.  
  698.     fwrite(header, 1, nHeader, fpout);
  699.  
  700.     fclose(fpout);
  701.  
  702.     sprintf(buffer, "Message prepared: file %x.upl", (int)uploadSeq);
  703.     MessageBox(buffer);
  704.  
  705.     return(TRUE);
  706. }
  707.  
  708. void CompTypeCb(Widget w, XtPointer client_data, XtPointer call_data)
  709. {
  710.     int i = 0;
  711.  
  712.     comptype = (int)client_data;
  713.  
  714.     for (;;)
  715.     {
  716.         if (comp_type_menu[i].Value == comptype)
  717.         {
  718.             XtVaSetValues(comptypebutton, XtNlabel, comp_type_menu[i].Label, NULL);
  719.             return;
  720.         }
  721.  
  722.         i++;
  723.     }
  724. }
  725.  
  726. void MesgSrcCb(Widget w, XtPointer client_data, XtPointer call_data)
  727. {
  728.     int i = 0;
  729.  
  730.     mesgsrc = (int)client_data;
  731.  
  732.     for (;;)
  733.     {
  734.         if (mesg_src_menu[i].Value == mesgsrc)
  735.         {
  736.             XtVaSetValues(mesgsrcbutton, XtNlabel, mesg_src_menu[i].Label, NULL);
  737.             return;
  738.         }
  739.  
  740.         i++;
  741.     }
  742. }
  743.  
  744. void FileTypeCb(Widget w, XtPointer client_data, XtPointer call_data)
  745. {
  746.     int i = 0;
  747.  
  748.     filetype = (int)client_data;
  749.  
  750.     for (;;)
  751.     {
  752.         if (file_type_menu[i].Value == filetype)
  753.         {
  754.             XtVaSetValues(filetypebutton, XtNlabel, file_type_menu[i].Label, NULL);
  755.             return;
  756.         }
  757.  
  758.         i++;
  759.     }
  760. }
  761.  
  762. int main(int argc, char **argv)
  763. {
  764.     static XtCallbackRec callback[2];
  765.     char *s;
  766.  
  767.     if ((s = getenv("SATELLITE")) == NULL)
  768.     {
  769.         printf("SATELLITE environment variable not set.\n");
  770.         return(1);
  771.     }
  772.  
  773.     strcpy(satelliteId, s);
  774.  
  775.     if ((s = getenv("MYCALL")) == NULL)
  776.     {
  777.         printf("MYCALL environment variable not set.\n");
  778.         return(1);
  779.     }
  780.  
  781.     strcpy(myCall, s);
  782.  
  783.     if ((s = getenv("BANNER")) == NULL)
  784.     {
  785.         if ((s = getenv("HOME")) != NULL)
  786.         {
  787.             strcpy(banner, s);
  788.             strcat(banner, "/.sig");
  789.         }
  790.         else
  791.         {
  792.             strcpy(banner, ".sig");
  793.         }
  794.     }
  795.     else
  796.         strcpy(banner, s);
  797.  
  798.     if (argc > 1)
  799.     {
  800.         fileName = argv[1];
  801.         ExtractDetails();
  802.     }
  803.  
  804.     toplevel = XtAppInitialize(&app_context, "Xpb", NULL, 0, &argc, argv,
  805.                 NULL, shell_args, XtNumber(shell_args));
  806.     XtVaSetValues(toplevel, XtNtitle, VERSION_STRING, NULL);
  807.  
  808.     dpy  = XtDisplay(toplevel);
  809.  
  810.     XtGetApplicationResources(toplevel, &resources,
  811.                 resource_list, XtNumber(resource_list),
  812.                 NULL, ZERO);
  813.  
  814.     compwindow = XtCreateManagedWidget("appForm", formWidgetClass,
  815.                 toplevel, form_args, XtNumber(form_args));
  816.  
  817.     callback[0].callback = QuitCb;
  818.     callback[0].closure  = toplevel;
  819.     button_args[0].value = (XtArgVal)callback;
  820.     button_args[1].value = (XtArgVal)"Quit";
  821.     button_args[2].value = (XtArgVal)resources.button_font;
  822.     quitbutton = XtCreateManagedWidget("quitButton", commandWidgetClass,
  823.                 compwindow, button_args, XtNumber(button_args));
  824.  
  825.     callback[0].callback = PrepareCb;
  826.     callback[0].closure  = toplevel;
  827.     button_args[0].value = (XtArgVal)callback;
  828.     button_args[1].value = (XtArgVal)"Prepare";
  829.     button_args[3].value = (XtArgVal)quitbutton;
  830.     preparebutton = XtCreateManagedWidget("prepareButton", commandWidgetClass,
  831.                 compwindow, button_args, XtNumber(button_args));
  832.  
  833.     callback[0].callback = BannerCb;
  834.     callback[0].closure  = toplevel;
  835.     button_args[0].value = (XtArgVal)callback;
  836.     button_args[1].value = (XtArgVal)"Append Banner";
  837.     button_args[3].value = (XtArgVal)preparebutton;
  838.     bannerbutton = XtCreateManagedWidget("appendButton", commandWidgetClass,
  839.                 compwindow, button_args, XtNumber(button_args));
  840.  
  841.     if (fileName != NULL)
  842.     {
  843.         callback[0].callback = QuoteCb;
  844.         callback[0].closure  = toplevel;
  845.         button_args[0].value = (XtArgVal)callback;
  846.         button_args[1].value = (XtArgVal)"Quote";
  847.         button_args[3].value = (XtArgVal)bannerbutton;
  848.         quotebutton = XtCreateManagedWidget("quoteButton", commandWidgetClass,
  849.                 compwindow, button_args, XtNumber(button_args));
  850.     }
  851.  
  852.     label_args[0].value = (XtArgVal)quitbutton;
  853.     label_args[1].value = (XtArgVal)"From:";
  854.     label_args[2].value = (XtArgVal)75;
  855.     label_args[3].value = (XtArgVal)resources.label_font;
  856.     fromlabel = XtCreateManagedWidget("fromLabel", labelWidgetClass,
  857.                 compwindow, label_args, XtNumber(label_args));
  858.  
  859.     label_args[0].value = (XtArgVal)fromlabel;
  860.     label_args[1].value = (XtArgVal)"To:";
  861.     tolabel = XtCreateManagedWidget("toLabel", labelWidgetClass,
  862.                 compwindow, label_args, XtNumber(label_args));
  863.  
  864.     label_args[0].value = (XtArgVal)tolabel;
  865.     label_args[1].value = (XtArgVal)"Title:";
  866.     titlelabel = XtCreateManagedWidget("titleLabel", labelWidgetClass,
  867.                 compwindow, label_args, XtNumber(label_args));
  868.  
  869.     label_args[0].value = (XtArgVal)titlelabel;
  870.     label_args[1].value = (XtArgVal)"Key Words:";
  871.     keywordslabel = XtCreateManagedWidget("keywordsLabel", labelWidgetClass,
  872.                 compwindow, label_args, XtNumber(label_args));
  873.  
  874.     label_args[0].value = (XtArgVal)keywordslabel;
  875.     label_args[1].value = (XtArgVal)"File Type";
  876.     filetypelabel = XtCreateManagedWidget("filetypeLabel", labelWidgetClass,
  877.                 compwindow, label_args, XtNumber(label_args));
  878.  
  879.     label_args[0].value = (XtArgVal)filetypelabel;
  880.     label_args[1].value = (XtArgVal)"Compression Type";
  881.     label_args[2].value = (XtArgVal)120;
  882.     comptypelabel = XtCreateManagedWidget("comptypeLabel", labelWidgetClass,
  883.                 compwindow, label_args, XtNumber(label_args));
  884.  
  885.     label_args[0].value = (XtArgVal)comptypelabel;
  886.     label_args[1].value = (XtArgVal)"Message Source";
  887.     mesgsrclabel = XtCreateManagedWidget("mesgsrcLabel", labelWidgetClass,
  888.                 compwindow, label_args, XtNumber(label_args));
  889.  
  890.     window_args[0].value = (XtArgVal)mesgsrclabel;
  891.     window_args[1].value = (XtArgVal)WhitePixel(dpy, DefaultScreen(dpy));
  892.     window_args[2].value = (XtArgVal)resources.text_font;
  893.     datawindow = XtCreateManagedWidget("messageText", asciiTextWidgetClass,
  894.                 compwindow, window_args, XtNumber(window_args));
  895.  
  896.     text_args[0].value = (XtArgVal)fromlabel;
  897.     text_args[1].value = (XtArgVal)quitbutton;
  898.     text_args[4].value = (XtArgVal)myCall;
  899.     text_args[5].value = (XtArgVal)resources.button_font;
  900.     text_args[6].value = (XtArgVal)WhitePixel(dpy, DefaultScreen(dpy));
  901.     fromtext = XtCreateManagedWidget("fromText", asciiTextWidgetClass,
  902.                 compwindow, text_args, XtNumber(text_args));
  903.  
  904.     text_args[0].value = (XtArgVal)tolabel;
  905.     text_args[1].value = (XtArgVal)fromlabel;
  906.     text_args[4].value = (XtArgVal)toCall;
  907.     totext = XtCreateManagedWidget("toText", asciiTextWidgetClass,
  908.                 compwindow, text_args, XtNumber(text_args));
  909.  
  910.     text_args[0].value = (XtArgVal)titlelabel;
  911.     text_args[1].value = (XtArgVal)tolabel;
  912.     text_args[4].value = (XtArgVal)title;
  913.     titletext = XtCreateManagedWidget("titleText", asciiTextWidgetClass,
  914.                 compwindow, text_args, XtNumber(text_args));
  915.  
  916.     text_args[0].value = (XtArgVal)keywordslabel;
  917.     text_args[1].value = (XtArgVal)titlelabel;
  918.     text_args[4].value = (XtArgVal)keywords;
  919.     keywordstext = XtCreateManagedWidget("keywordsText", asciiTextWidgetClass,
  920.                 compwindow, text_args, XtNumber(text_args));
  921.  
  922.     menu_button_args[0].value = (XtArgVal)file_type_menu[0].Label;
  923.     menu_button_args[1].value = (XtArgVal)filetypelabel;
  924.     menu_button_args[2].value = (XtArgVal)keywordslabel;
  925.     menu_button_args[3].value = (XtArgVal)175;
  926.     menu_button_args[4].value = (XtArgVal)resources.button_font;
  927.     filetypebutton = XtCreateManagedWidget("filetypeButton", menuButtonWidgetClass,
  928.                 compwindow, menu_button_args, XtNumber(menu_button_args));
  929.  
  930.     createMenuPopup(filetypebutton, resources.menu_font, file_type_menu,
  931.                 XtNumber(file_type_menu), FileTypeCb);
  932.  
  933.     text_args[0].value = (XtArgVal)filetypebutton;
  934.     text_args[1].value = (XtArgVal)keywordslabel;
  935.     text_args[3].value = (XtArgVal)317;
  936.     text_args[4].value = (XtArgVal)filetype_text;
  937.     filetypetext = XtCreateManagedWidget("filetypeText", asciiTextWidgetClass,
  938.                 compwindow, text_args, XtNumber(text_args));
  939.  
  940.     menu_button_args[0].value = (XtArgVal)comp_type_menu[0].Label;
  941.     menu_button_args[1].value = (XtArgVal)comptypelabel;
  942.     menu_button_args[2].value = (XtArgVal)filetypelabel;
  943.     menu_button_args[3].value = (XtArgVal)130;
  944.     comptypebutton = XtCreateManagedWidget("comptypeButton", menuButtonWidgetClass,
  945.                 compwindow, menu_button_args, XtNumber(menu_button_args));
  946.  
  947.     createMenuPopup(comptypebutton, resources.menu_font, comp_type_menu,
  948.                 XtNumber(comp_type_menu), CompTypeCb);
  949.  
  950.     text_args[0].value = (XtArgVal)comptypebutton;
  951.     text_args[1].value = (XtArgVal)filetypelabel;
  952.     text_args[4].value = (XtArgVal)comptype_text;
  953.     comptypetext = XtCreateManagedWidget("comptypeText", asciiTextWidgetClass,
  954.                 compwindow, text_args, XtNumber(text_args));
  955.  
  956.     menu_button_args[0].value = (XtArgVal)mesg_src_menu[0].Label;
  957.     menu_button_args[1].value = (XtArgVal)mesgsrclabel;
  958.     menu_button_args[2].value = (XtArgVal)comptypelabel;
  959.     mesgsrcbutton = XtCreateManagedWidget("mesgsrcButton", menuButtonWidgetClass,
  960.                 compwindow, menu_button_args, XtNumber(menu_button_args));
  961.  
  962.     createMenuPopup(mesgsrcbutton, resources.menu_font, mesg_src_menu,
  963.                 XtNumber(mesg_src_menu), MesgSrcCb);
  964.  
  965.     text_args[0].value = (XtArgVal)mesgsrcbutton;
  966.     text_args[1].value = (XtArgVal)comptypelabel;
  967.     text_args[4].value = (XtArgVal)mesgsrc_text;
  968.     mesgsrctext = XtCreateManagedWidget("mesgsrcText", asciiTextWidgetClass,
  969.                 compwindow, text_args, XtNumber(text_args));
  970.  
  971.     createMessagePopup(resources.bold_font, resources.button_font);
  972.  
  973.     XawTextSetInsertionPoint(fromtext,  strlen(myCall));
  974.     XawTextSetInsertionPoint(totext,    strlen(toCall));
  975.     XawTextSetInsertionPoint(titletext, strlen(title));
  976.  
  977.     XtRealizeWidget(toplevel);
  978.                 
  979.     XtAppMainLoop(app_context);
  980.     
  981.     return(0);
  982. }
  983.  
  984.